/*****************************
Author:         Gary A. Bushey
Project:        SharePointSiteMap
Date Created:   6 Jan 2008
Date Modified:  6 Jan 2008
Purpose:        To show a security trimmed list of all sites either starting at the root or a specific URL
Modifier: 
Modified Date:
Modification: 
*****************************/

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Web;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;

namespace SharePoint.Navigation.SiteMap
{
    [Guid("1e900b56-1f33-4772-b5b9-9df73612c40d")]
    public class SharePointSiteMap : System.Web.UI.WebControls.WebParts.WebPart
    {
        string _TopSiteURL;
        bool _StartAtTopLevel = false;

        [WebBrowsable(true),
        Personalizable(PersonalizationScope.Shared),
        FriendlyName("Start showing sites from the top node?"),
        Category("SharePoint Navigation"),
        DefaultValue(true)]
        public bool StartAtTopLevel
        {
            get
            {
                return _StartAtTopLevel;
            }
            set
            {
                _StartAtTopLevel = value;
            }
        }

        [WebBrowsable(true),
        Personalizable(PersonalizationScope.Shared),
        FriendlyName("The URL of the site to start from"),
       Category("SharePoint Navigation")]
        public string StartNodeURL
        {
            get
            {
                return _TopSiteURL;
            }
            set
            {
                _TopSiteURL = value;
            }
        }

        protected override void CreateChildControls()
        {
            //No need to show the title of the webpart
            this.ChromeType = PartChromeType.None;
           
            try
            {
                //Make sure at least one of the 2 parameters is filled in
                if (_StartAtTopLevel || _TopSiteURL.Length > 0)
                {
                    base.CreateChildControls();
                    
                    //Determine where to start from, either the top level or the specified site
                    SPWeb startNode;
                    SPSite currentSite = SPContext.Current.Site;
                    if (_StartAtTopLevel)
                    {
                        startNode = currentSite.RootWeb;
                        //startNode = portalSiteMap.RootNode;
                    }
                    else
                    {
                        string tmpUrl = _TopSiteURL;
                        if ((_TopSiteURL.Contains("http://") == false) && _TopSiteURL.Contains("https://")==false)
                        {
                            tmpUrl = currentSite.Url + _TopSiteURL;
                        }
                        SPSite startSite = new SPSite(tmpUrl);
                        startNode = startSite.OpenWeb();
                        startSite.Dispose();
                    }
                    
                    //Create the treeview that will show the sites
                    SPTreeView siteTreeView = new SPTreeView();
                    //Default to showing only 10 levels deep.
                    siteTreeView.ExpandDepth = 10;

                    //Add the base node that all the sites will be added to
                    siteTreeView.Nodes.Add(new TreeNode(startNode.Title, startNode.Url, "", startNode.Url, ""));

                    //Start at this base node
                    TreeNode baseNode = siteTreeView.Nodes[0];

                    //Call the function to load the tree.  This will be called recursively.
                    AddSiteNodes(baseNode, startNode.Webs);

                    //Add the tree to the controls on the page to show.
                    Controls.Add(siteTreeView);
                }
                else
                {
                    Controls.Clear();
                    Label errorMessage = new Label();
                    errorMessage.Text = "Enable the web part to start either at the root node or at a specific Url";
                    Controls.Add(errorMessage);
                }
            }
            catch (Exception ex)
            {
                Controls.Clear();
                Label errorMessage = new Label();
                errorMessage.Text = "There was an error in the code.  Please contact your system administrator and rely the following " +
                    "message: " + ex.Message;
                Controls.Add(errorMessage);
            }

        }

        private void AddSiteNodes(TreeNode currentBaseNode, SPWebCollection siteMapNodes)
        {
            try
            {
                foreach (SPWeb singleSiteMapNode in siteMapNodes)
                {
                    TreeNode thisNode = new TreeNode(singleSiteMapNode.Title, singleSiteMapNode.Url, "", singleSiteMapNode.Url, "");
                    if (singleSiteMapNode.Webs.Count > 0)
                    {
                        AddSiteNodes(thisNode, singleSiteMapNode.Webs);
                    }
                    currentBaseNode.ChildNodes.Add(thisNode);
                }
            }
            catch (Exception e)
            {
                Controls.Clear();
                Label errorMessage = new Label();
                errorMessage.Text = "There was an error in the code.  Please contact your system administrator and rely the following " +
                    "message: " + e.Message;
                Controls.Add(errorMessage);
            }

        }
    }
}
